﻿using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Framework.Interface;
using Framework.Singleton;
using Framework.Task;
using UnityEngine;

namespace Framework.Manager
{
    public class TaskProgressArgs : IListener
    {
        public float progress;
    }
    
    public class TaskManager : Singleton<TaskManager>, IManager
    {
        private readonly List<Task.Task> queue = new List<Task.Task>();
        private int step;
        private int factor;
        private float progress;

        public async UniTask Initialize()
        {
            await UniTask.CompletedTask;
        }

        public void Shutdown()
        {
            
        }

        public void Add(Task.Task task)
        {
            if (task == null)
                return;
            
            queue.Add(task);
            factor += task.factor > 0 ? task.factor : 0;
        }

        public async UniTask Start()
        {
            try
            {
                step = queue.Count > 0 ? 0 : -1;
                if (step == -1)
                {
                    Debug.LogWarning("[TaskManager] queue of task is empty, confirm pls.");
                    return;
                }
            
                // 最后重置一下
                Add(new Task_LoadingEnd());
                
                while (step >= 0)
                {
                    Task.Task task = queue[step];

                    if (task.state == TaskState.Idle)
                        await task.Start();
                    else if (task.state == TaskState.Running)
                        await UniTask.WaitForSeconds(0.01f);
                    else if (task.state == TaskState.Finished)
                    {
                        step += 1;
                        
                        progress += factor > 0 ? (float)task.factor / factor : 0;
                        // 发送到加载界面
                        EventsManager.Instance.Broadcast(new TaskProgressArgs { progress = progress });
                    
                        // 结束
                        if (step >= queue.Count)
                            break;
                        
                        await UniTask.WaitForSeconds(0.01f);
                    }
                    else
                    {
                        Debug.LogError("[TaskManager] worker fatal exception.");
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Log($"[TaskManager] task running occurs error, reason: {e.Message}");
            }
        }
        
        public void OnProgress(float pgs)
        {
            if (step <= 0 || step > queue.Count)
                return;

            Task.Task task = queue[step];
            pgs = pgs >= 0 && pgs <= 1 ? pgs : 0;
            float total = progress + (factor > 0 ? ((float) task.factor * pgs / factor) : 0);
            
            // 发送到加载界面
            EventsManager.Instance.Broadcast(new TaskProgressArgs { progress = total });
        }

        public void Reset()
        {
            for (int i = 0; i < queue.Count; i++)
            {
                queue[i].Cleanup();
            }
            queue.Clear();
            step = -1;
            progress = 0;
            factor = 0;
        }
    }
}